<?php
/**
 * DataSourceManager
 *
 * @category	DataSource
 * @package		dayscript.datasource
 * @subpackage
 * @author		Nelson Daza <ndaza@dayscript.com>
 * @copyright	2009 Dayscript Ltda.
 * @license
 * @version		1.0
 * @version		$Revision: 0 $
 * @filesource
 * @link		http://www.dayscript.com
 * @link		{docsLink}
 * @uses
 * @since		1.0
 * @modifiedby	$LastChangedBy: Nelson Daza $
 * @modified	$Date: 2009-08-13 $
 */

namespace dayscript\datasource;

/**
 * DataSourceManager
 *
 * Singleton
 *
 * @category	DataSource
 * @package		dayscript.datasource
 * @subpackage
 * @author		Nelson Daza <ndaza@dayscript.com>
 * @copyright	2009 Dayscript Ltda.
 * @license
 * @version		1.0
 * @link		http://www.dayscript.com
 * @link		{docsLink}
 * @uses		\dayscript\Map, \dayscript\Enviroment, \dayscript\datasource\DataSource, \dayscript\log\LogManager
 * @since		1.0
 * @modifiedby	$LastChangedBy: Nelson Daza $
 * @modified	$Date: 2009-08-13 $
 */
class DataSourceManager	{
	/**
	 * Data sources list
	 * @var Hashtable $sources
	 */
	private static $sources = null;
	/**
	 * Default DataSource
	 * @var string $default
	 */
	private static $default = null;
	/**
	 * DataSourceManager constructor
	 * @return DataSourceManager
	 */
	private function __construct( )	{
		
	}
	/**
	 * Init member values
	 */
	public static function init( )	{
		if( self::$sources == null )	{
			self::$sources = new \dayscript\Map( );
			
			$config = \dayscript\Enviroment::config( 'DATA_SOURCES', new \dayscript\Map( ) );
			self::$default = \dayscript\Enviroment::config( 'DATA_SOURCE', 'default' );
			
			foreach( $config as $name => $ds )	{
				if( $ds['datasource'] )	{
					$className = $ds['datasource'];
					$dataSource = new $className( );
					$dataSource->init( $name, $ds );
					// $dataSource->openConnection( );	// Do not open it if you don't use it.
					self::$sources[$name] = $dataSource;
				}
			}
		}
	}
	/**
	 * Registers its shutdown function
	 */
	public static function registerShutdown( )	{
		\register_shutdown_function( array( __CLASS__, 'shutdownHandler' ) );
	}
	/**
	 * Add a named dataSource.
	 *
	 * This does nothing and returns false if the dataSource is already registered.
	 *
	 * @param \dayscript\datasource\DataSource $datasource
	 */
	public static function addDS( \dayscript\datasource\DataSource $datasource )	{
		if( isset( self::$sources[$datasource->getName( )] ) )
			return false;
		self::$sources[$datasource->getName( )] = $datasource;
		return true;
	}
	/**
	 * Method to find a named source.
	 *
	 * @param string $name
	 * @return DataSource|null
	 */
	public static function getDS( $name = null )	{
		if( $name == null )
			$name = self::$default;
		return self::$sources[$name];
	}
	/**
	 * Get an array of known sources names.
	 *
	 * @return array $keys
	 */
	public static function getDSNames( )	{
		return self::$sources->keys( );
	}
	/**
	 * DataSource load function
	 *
	 * @param string $className
	 * @return boolean $loaded
	 */
	public static function loadDS( $className )	{
		foreach ( self::$sources as $source )	{
			$source->loadClass( $className );
			if( \class_exists( $className, false ) )
				return true;
		}
		\trigger_error( 'Class "' . $className . '" was not loaded using: ' . \count( self::$loaders ) . ' loader(s).', \dayscript\log\LogManager::LOG_ERROR );
		return false;
	}
	/**
	 * Global script shutdown Handler.
	 * This will close and destroy every each datasource connection.
	 * @param mixed $params
	 * @param bool $flush
	 * @todo I don't know what will happend if the LogManager use a Datasource for storing.
	 */
	public static function shutdownHandler( $params = null, $flush = true )	{
		\dayscript\log\LogManager::log( 'SHUTDOWN DataSourceManager (5).', \dayscript\log\LogManager::LOG_USER_INFO );
		if (self::$sources != null )
			foreach ( self::$sources as $ds )
				$ds->destroy( );
		self::$sources = null;
		if ( $flush )
			\flush( );
	}
}